package com.jinyou.utils.spring;

import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * 类名称：SpringContextHolder 类描述： 以静态变量保存Spring ApplicationContext,
 * 可在任何代码任何地方任何时候中取出ApplicaitonContext. 创建人：Jahnke 1029777564@qq.com
 * 创建时间：2016年8月13日 下午12:14:03 修改备注：
 */
@Configuration
@Component
public class SpringContextHolder implements ApplicationContextAware {
    private static ApplicationContext applicationContext;

    /**
     * 实现ApplicationContextAware接口的context注入函数, 将其存入静态变量.
     */
    public void setApplicationContext(ApplicationContext applicationContext) {
        SpringContextHolder.applicationContext = applicationContext;
    }

    /**
     * @throws
     * @方法名: getApplicationContext
     * @方法描述:取得存储在静态变量中的ApplicationContext.
     * @方法参数 @return
     * @返回类型 ApplicationContext
     */
    public static ApplicationContext getApplicationContext() {
        checkApplicationContext();

        return applicationContext;
    }

    /**
     * @throws
     * @方法名: getBean
     * @方法描述:从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
     * @方法参数 @param name
     * @方法参数 @return
     * @返回类型 T
     */
    @SuppressWarnings("unchecked")
    public static <T> T getBean(String name) {
        checkApplicationContext();

        return (T) applicationContext.getBean(name);
    }

    /**
     * @throws
     * @方法名: getBean
     * @方法描述: * 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型. 如果有多个Bean符合Class,
     * 取出第一个.
     * @方法参数 @param clazz
     * @方法参数 @return
     * @返回类型 T
     */
    @SuppressWarnings("unchecked")
    public static <T> T getBean(Class<T> clazz) {
        checkApplicationContext();

        Map beanMaps = applicationContext.getBeansOfType(clazz);
        if (beanMaps != null && !beanMaps.isEmpty()) {
            return (T) beanMaps.values().iterator().next();
        } else {
            return null;
        }
    }

    private static void checkApplicationContext() {
        if (applicationContext == null) {
            throw new IllegalStateException(
                    "applicaitonContext未注入,请在spring-servlet.xml中定义SpringContextHolder");
        }

    }
}
